import { ipcMain } from "electron";
import fsp from "node:fs/promises";
import fs from "node:fs";
import path from "node:path";
import type { ReadDirOptions } from "@common/ipc-types.ts";
import FastGlob from "fast-glob";

(() => {
  // 读取文件,返回Buffer
  ipcMain.handle("fs.readFile", async (_, ...args: Parameters<typeof fsp.readFile>) => {
    if (!fs.existsSync(args[0] as string)) {
      return Buffer.alloc(0);
    }
    return await fsp.readFile(...args);
  });

  // 读取文件,返回文本
  ipcMain.handle("fs.readFileText", async (_, ...args: Parameters<typeof fsp.readFile>) => {
    if (!fs.existsSync(args[0] as string)) {
      return "";
    }
    return await fsp.readFile(...args).then(data => data.toString());
  });

  ipcMain.handle("fs.readFileJson", async (_, ...args: Parameters<typeof fsp.readFile>) => {
    if (!fs.existsSync(args[0] as string)) {
      return null;
    }
    return await fsp.readFile(...args).then(data => JSON.parse(data.toString()));
  });

  // 写入文件
  ipcMain.handle("fs.writeFile", async (_, ...args: Parameters<typeof fsp.writeFile>) => {
    const [file, content, options] = args;
    let isCsv = false;
    if (typeof file === "string") {
      const dir = path.dirname(file);
      await fsp.mkdir(dir, { recursive: true });
      isCsv = file.toLowerCase().endsWith(".csv");
    }
    if (isCsv) {
      // 对CSV文件写入BOM,防止乱码
      await fsp.writeFile(file, Buffer.from("\xEF\xBB\xBF", "binary"));
      await fsp.appendFile(file, content as string);
    } else {
      await fsp.writeFile(file, content, options);
    }
  });

  ipcMain.handle("fs.exists", (_, file: string) => fs.existsSync(file));
  ipcMain.handle("fs.exists1", (_, file: string) => {
    return new Promise<boolean>(resolve => {
      fs.access(file, fs.constants.O_RDONLY, (err: NodeJS.ErrnoException | null) => {
        resolve(!err);
      });
    });
  });

  ipcMain.handle("fs.mkdir", async (_, ...args: Parameters<typeof fsp.mkdir>) => {
    const dir = args[0] as string;
    const b = fs.existsSync(dir);
    if (b) {
      return dir;
    }
    return await fsp.mkdir(...args);
  });

  ipcMain.handle("fs.rm", (_, ...args: Parameters<typeof fsp.rm>) => fsp.rm(...args));

  ipcMain.handle("fs.copyFile", (_, ...args: Parameters<typeof fsp.copyFile>) => {
    return fsp.copyFile(...args);
  });

  ipcMain.handle("fs.readdir", async (_, dir: string, options?: ReadDirOptions) => {
    const { filter = "**", depth = 1, onlyFiles = false, onlyDirectories = false } = options || {};
    return await FastGlob.async(filter, {
      cwd: dir,
      deep: depth,
      onlyDirectories,
      onlyFiles,
      absolute: true,
      ignore: options?.ignore,
      dot: options?.dot,
    });
  });
})();
